package com.hy.proxy.server.utils;

import com.google.gson.reflect.TypeToken;
import com.hy.proxy.common.JsonUtils;
import com.hy.proxy.common.LogUtils;
import com.hy.proxy.common.ThreadPoolUtils;
import com.hy.proxy.core.AutomateProxyTool;
import com.hy.proxy.core.entity.*;
import com.hy.proxy.core.util.ProxyUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Author: hy
 * @Date: Created in 2019/10/2/13:20
 * @Description: redis 工具类
 * @Version: 1.0
 */
@Slf4j
@Component
public class RedisUtils {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 操作字符串
     */
    private ValueOperations<String, String> operations;

    {

//        operations = stringRedisTemplate.opsForValue();

        // key采用String的序列化方式
//      stringRedisTemplate.setKeySerializer(new StringRedisSerializer());

//      // hash的key也采用String的序列化方式
//      stringRedisTemplate.setHashKeySerializer(new StringRedisSerializer());
//
//      // value序列化方式采用jackson
//      stringRedisTemplate.setValueSerializer(new StringRedisSerializer());

        // hash的value序列化方式采用jackson
//      redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer());
    }

    public boolean insertProxy() {

        operations = stringRedisTemplate.opsForValue();

        boolean hasSucceed = true;

        try {


            long start = System.currentTimeMillis();

            AutomateProxyTool.start();
            for (Proxy.ProxyType value : Proxy.ProxyType.values()) {
                this.setProxyByProxyType(value);
            }

//            ThreadPoolUtils.Instance.executor(() -> {
//                List<Proxy> ssrList = Site.getProxyList(Proxy.ProxyType.SSR);
//                String jsonStr = ProxyUtils.toJsonByProxyList(ssrList);
//                stringRedisTemplate.delete("ssr");
//                operations.set("ssr", jsonStr);
//            });
//
//            ThreadPoolUtils.Instance.executor(() -> {
//                List<Proxy> ssList = Site.getProxyList(Proxy.ProxyType.SS);
//                String jsonStr1 = ProxyUtils.toJsonByProxyList(ssList);
//                stringRedisTemplate.delete("ss");
//                operations.set("ss", jsonStr1);
//            });
//
//            ThreadPoolUtils.Instance.executor(() -> {
//                List<Proxy> ssList = Site.getProxyList(Proxy.ProxyType.V2RAY);
//                String jsonStr1 = ProxyUtils.toJsonByProxyList(ssList);
//                stringRedisTemplate.delete("v2");
//                operations.set("v2ray", jsonStr1);
//            });

            log.info(LogUtils.getCurrentMethodName() + ": 执行时长 - " + (System.currentTimeMillis() - start));

        } catch (Exception e) {
            hasSucceed = false;
        } finally {

            ThreadPoolUtils.Instance.shutdown();
        }

        return hasSucceed;

    }

    public void setProxyByProxyType(Proxy.ProxyType type) {
        List<Proxy> proxyList = GlobalObject.Instance.getProxyListByProxyType(type);
        String jsonStr = ProxyUtils.toJsonByProxyList(proxyList);
        operations.set(type.name().toLowerCase(), jsonStr);
    }

    /**
     * 通过ProxyType从Redis缓存中获取Proxy对象
     *
     * @param type ProxyType 枚举
     * @return
     */
    public String findProxyByProxyType(Proxy.ProxyType type) {

        operations = stringRedisTemplate.opsForValue();

        String proxyStr = null;

        List<Proxy> proxyList = null;

        if (type == Proxy.ProxyType.SSR) {
            proxyStr = operations.get("ssr");
            proxyList = JsonUtils.getGson().fromJson(proxyStr, new TypeToken<List<SSR>>() {
            }.getType());
        } else if (type == Proxy.ProxyType.V2RAY) {
            proxyStr = operations.get("v2");
            proxyList = JsonUtils.getGson().fromJson(proxyStr, new TypeToken<List<V2ray>>() {
            }.getType());
        } else if (type == Proxy.ProxyType.SS) {
            proxyStr = operations.get("ss");
            proxyList = JsonUtils.getGson().fromJson(proxyStr, new TypeToken<List<SS>>() {
            }.getType());
        }

        return ProxyUtils.encoderProxyList(proxyList);
    }
}
